import React, { useState, useRef, useEffect } from 'react';
import { Card, Button, Table, Modal, FormInstance, message } from 'antd';
import { reqAddRole, reqRoles, AxiosResponse, reqUpdateRole } from '../../api';
import userUnit from '../../utils/memory_utils';
import formatTime from '../../utils/date';
import AddForm from './AddForm';
import AuthForm from './AuthForm';

type RoleInfo = {
    menus: string[];
    _id: string;
    name: string;
    create_time: number;
    __v: 0;
    auth_time?: number;
    auth_name?: string;
};

type RowListMethod = {
    onClick: () => void;
};

type Cloumns = {
    title: string;
    dataIndex: string;
    render?: (time: React.Key) => string;
};

const columns: Cloumns[] = [
    {
        title: '角色名称',
        dataIndex: 'name'
    },
    {
        title: '创建时间',
        dataIndex: 'create_time',
        render(time) {
            return typeof time === 'number' ? formatTime(new Date(time)) : time;
        }
    },
    {
        title: '授权时间',
        dataIndex: 'auth_time',
        render(time) {
            return typeof time === 'number' ? formatTime(new Date(time)) : time;
        }
    },
    {
        title: '授权人',
        dataIndex: 'auth_name'
    }
];

// 角色路由组件
const Role: React.FC = () => {
    const [isLoading, setLoading] = useState<boolean>(false);
    const [isShowAdd, setShowAdd] = useState<boolean>(false);
    const [isShowAuth, setShowAuth] = useState<boolean>(false);
    const [roles, setRoles] = useState<RoleInfo[]>([]);
    const [role, setRoleId] = useState<Partial<RoleInfo>>({});
    const addRoleRef = useRef<FormInstance | null>(null);
    const authRef = useRef<(() => React.Key[]) | null>(null);
    const onRow = (role: RoleInfo): RowListMethod => ({
        onClick() {
            setRoleId(role);
        }
    });
    const addAsyncRole = async (): Promise<void> => {
        const { roleName }: { roleName: string; } = await addRoleRef.current!.validateFields();
        const { data }: AxiosResponse<{
            status: 0;
            data: Omit<RoleInfo, 'auth_time' | 'auth_name'>;
        } | {
            status: 1;
            msg: string;
        }> = await reqAddRole(roleName);
        addRoleRef.current!.resetFields();
        setShowAdd(false);
        if (data.status === 0) {
            message.success('添加角色成功');
            setRoles(roles => [...roles, data.data]);
            return;
        }
        message.error(data.msg);
    };
    const updateAsyncRole = async (): Promise<void> => {
        const menus: React.Key[] = authRef.current!();
        const { data }: AxiosResponse<{
            status: 0;
            data: Required<RoleInfo>;
        }> = await reqUpdateRole({ ...role, menus, auth_time: Date.now(), auth_name: userUnit.user?.username });
        setShowAuth(false);
        if (data.status === 0) {
            message.success('设置权限成功');
            setRoles(roles => roles.map(role => role._id === data.data._id ? data.data : role));
        }
    };
    const getAsyncRoles = async (): Promise<void> => {
        setLoading(true);
        const { data }: AxiosResponse<{
            status: 0;
            data: RoleInfo[];
        } | {
            status: 1;
            msg: string;
        }> = await reqRoles();
        setLoading(false);
        if (data.status === 0) {
            setRoles(data.data);
        }
    };
    const title: React.ReactNode = (
        <span>
            <Button type="primary" onClick={() => setShowAdd(true)}>创建角色</Button> &nbsp;
            <Button type="primary" disabled={!role._id} onClick={() => setShowAuth(true)}>设置角色权限</Button>
        </span>
    );
    useEffect(() => {
        getAsyncRoles();
    }, []);
    return (
        <Card title={title}>
            <Table
                bordered
                rowKey="_id"
                pagination={{
                    defaultPageSize: 5
                }}
                rowSelection={{
                    type: 'radio',
                    selectedRowKeys: [role._id || ''],
                    onSelect(role: RoleInfo): void {
                        setRoleId(role);
                    }
                }}
                loading={isLoading}
                onRow={onRow}
                dataSource={roles}
                columns={columns}
            />
            <Modal destroyOnClose title="添加角色" visible={isShowAdd} onOk={addAsyncRole} onCancel={() => {
                addRoleRef.current!.resetFields();
                setShowAdd(false);
            }} okText="确认" cancelText="取消">
                <AddForm addRoleRef={addRoleRef} />
            </Modal>
            <Modal destroyOnClose title="设置角色权限" visible={isShowAuth} onOk={updateAsyncRole} onCancel={() => {
                setShowAuth(false);
            }} okText="确认" cancelText="取消">
                <AuthForm role={role} authRef={authRef} />
            </Modal>
        </Card>
    );
};

export default Role;